Warning 20 range: also walk through let/use bindings (follow-up to #19504)#19896
Open
T-Gro wants to merge 1 commit into
Open
Warning 20 range: also walk through let/use bindings (follow-up to #19504)#19896T-Gro wants to merge 1 commit into
T-Gro wants to merge 1 commit into
Conversation
- Walk through let/use bindings in addition to Sequential when locating
the offending expression for warning 20. Fixes the case Eugene flagged:
for _ in [] do
let x = 1
x
- Fix wrong issue link (#5735 -> #5418) in code comment, release notes,
and test annotations.
- Add regression tests for the let/use case (single + nested bindings).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
❗ Release notes requiredYou can open this PR in browser to add release notes: open in github.dev
Warning No PR link found in some release notes, please consider adding it.
|
abonie
reviewed
Jun 8, 2026
abonie
left a comment
Member
There was a problem hiding this comment.
🤖 AI-generated review — verify before acting on findings.
| |> typecheck | ||
| |> shouldFail | ||
| |> withSingleDiagnostic (Warning 20, Line 5, Col 5, Line 5, Col 10, | ||
| "The result of this expression has type 'int' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'.") |
Member
There was a problem hiding this comment.
[Test Coverage / LOW] The PR title and release note both say "let/use", but the two new tests only cover let bindings. The use path goes through the identical code (SynExpr.LetOrUse is one union case for both), so it works — but there is no regression guard for it.
Suggested addition:
// https://github.com/dotnet/fsharp/issues/5418
[<Fact>]
let ``Warn On Last Expression In For Loop - non-unit after use binding``() =
FSharp """
type D() =
interface System.IDisposable with
member _.Dispose() = ()
member _.Value = 1
for _ in [] do
use d = new D()
d.Value
"""
|> typecheck
|> shouldFail
|> withSingleDiagnostic (Warning 20, Line 8, Col 5, Line 8, Col 12,
"The result of this expression has type 'int' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'.")
abonie
approved these changes
Jun 8, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #19504 addressing review feedback from @auduchinok.
#19504 fixed warning 20 ("expression is implicitly ignored") to point at the last expression of a sequential body inside
for/while. The walk only descended throughSynExpr.Sequential, so when the last expression was the body of alet/usebinding, the squiggle covered the wholeletexpression instead of just the offending tail:This PR also descends through
SynExpr.LetOrUse, so the squiggle lands onxalone in cases like the one above.It also corrects the issue reference cited by the original PR (#5418 — "Wrong expression is ignored warning range"; the previously cited #5735 is unrelated to this diagnostic).
Tracking: #5418